﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Web;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	[Serializable]
	public abstract class SpecialPageConfiguration
	{
		public virtual int AreaIndex { get; set; }
		public virtual string AreaId { get; set; }
		public virtual int ModuleId { get; set; }
		public virtual string ModuleType { get; set; }
	}



	/// <summary>
	/// 链接项。
	/// </summary>
	public class NavigationItem
	{
		/// <summary>
		/// 链接的Url。
		/// </summary>
		public string Url { get; set; }

		/// <summary>
		/// 链接的文本。
		/// </summary>
		public string Text { get; set; }
	}
	
	/// <summary>
	/// 专题页面解析时，由模块传递给页面的附加信息。
	/// </summary>
	public class SpecialPageInfo
	{
		#region Metas
		private static readonly string DefaultMetaKeywords = ConfigurationManager.AppSettings["MetaKeywords"];
		private static readonly string DefaultMetaDescription = ConfigurationManager.AppSettings["MetaDescription"];
		private static readonly string DefaultMetaAuthor = ConfigurationManager.AppSettings["MetaAuthor"];
		private static readonly string DefaultMetaCopyright = ConfigurationManager.AppSettings["MetaCopyright"];
		public static readonly string TitleSuffix = ConfigurationManager.AppSettings["PageTitleSuffix"];

		private Dictionary<string, string> _metas;
		public Dictionary<string, string> Metas
		{
			get
			{
				if (_metas == null)
				{
					_metas = new Dictionary<string, string>();

					if (!string.IsNullOrEmpty(DefaultMetaKeywords)) _metas[MetaKeywords] = DefaultMetaKeywords;
					if (!string.IsNullOrEmpty(DefaultMetaDescription)) _metas[MetaDescriptionKey] = DefaultMetaDescription;
					if (!string.IsNullOrEmpty(DefaultMetaAuthor)) _metas[MetaAuthorKey] = DefaultMetaAuthor;
					if (!string.IsNullOrEmpty(DefaultMetaCopyright)) _metas[MetaCopyrightKey] = DefaultMetaCopyright;
				}

				return _metas;
			}
		}

		public const string MetaKeywordsKey = "keywords";
		public virtual string MetaKeywords
		{
			get { return Metas.ContainsKey(MetaKeywordsKey) ? Metas[MetaKeywordsKey] : null; }
			set { Metas[MetaKeywordsKey] = value; }
		}

		public string MetaDescriptionKey = "description";
		public virtual string MetaDescription
		{
			get { return Metas.ContainsKey(MetaDescriptionKey) ? Metas[MetaDescriptionKey] : null; }
			set { Metas[MetaDescriptionKey] = value; }
		}

		public string MetaAuthorKey = "author";
		public virtual string MetaAuthor
		{
			get { return Metas.ContainsKey(MetaAuthorKey) ? Metas[MetaAuthorKey] : null; }
			set { Metas[MetaAuthorKey] = value; }
		}

		public string MetaCopyrightKey = "Copyright";
		public virtual string MetaCopyright
		{
			get { return Metas.ContainsKey(MetaCopyrightKey) ? Metas[MetaCopyrightKey] : null; }
			set { Metas[MetaCopyrightKey] = value; }
		}
		#endregion

		#region HeadIncludeFiles
		private Dictionary<string, IncludeFileType> _headIncludeFiles;
		public Dictionary<string, IncludeFileType> HeadIncludeFiles
		{
			get
			{
				if (_headIncludeFiles == null) _headIncludeFiles = new Dictionary<string, IncludeFileType>();
				return _headIncludeFiles;
			}
		}

		/// <summary>
		/// 注册头部包含文件。
		/// </summary>
		/// <param name="fileUrl">包含文件的Url。</param>
		/// <param name="fileType">包含文件的类别。</param>
		public void RegisterHeadIncludeFile(string fileUrl, IncludeFileType fileType)
		{
			Dictionary<string, IncludeFileType> headIncludeFiles = HeadIncludeFiles;
			if (!headIncludeFiles.ContainsKey(fileUrl))
				headIncludeFiles[fileUrl] = fileType;
		}

		public void RegisterHeadIncludeFile(Dictionary<string, IncludeFileType> files)
		{
			foreach (var file in files)
				RegisterHeadIncludeFile(file.Key, file.Value);
		}

		/// <summary>
		/// 移除头部文件注册。
		/// </summary>
		/// <param name="fileUrl"></param>
		public void UnregisterHeadIncludeFile(string fileUrl)
		{
			Dictionary<string, IncludeFileType> headIncludeFiles = HeadIncludeFiles;
			if (headIncludeFiles.ContainsKey(fileUrl))
				headIncludeFiles.Remove(fileUrl);
		}

		public string BuildHeadIncludeHtml(string fileUrl, IncludeFileType fileType)
		{
			switch (fileType)
			{
				case IncludeFileType.CSS:
					return @"<link rel=""stylesheet"" type=""text/css"" href=""" + fileUrl + @""" />";
				case IncludeFileType.JS:
					return @"<script type=""text/javascript"" src=""" + fileUrl + @"""></script>";
			}
			return fileUrl;
		}
		#endregion

		#region CurrentLocation
		private List<NavigationItem> _locations;

		/// <summary>
		/// 当前位置列表。
		/// </summary>
		public List<NavigationItem> Locations
		{
			get
			{
				if (_locations == null)
					_locations = new List<NavigationItem>();
				return _locations;
			}
		}
		#endregion

		/// <summary>
		/// 模板CSS路径。
		/// </summary>
		public string[] TemplateCssUrls { get; set; }

		/// <summary>
		/// 模块计数器。
		/// </summary>
		public int ModuleCounter { get; set; }

		/// <summary>
		/// 页面标题。
		/// </summary>
		public string Title { get; set; }



		public string BuildCssHtml()
		{
			StringBuilder sb = new StringBuilder();

			if (TemplateCssUrls != null)
			{
				foreach (var url in TemplateCssUrls)
				{
					sb.AppendLine(@"<link rel=""stylesheet"" href=""" + url + @""" type=""text/css"" /> ");
				}
			}

			return sb.ToString();
		}
		
		public string BuildHeadAttachedHtml()
		{
			StringBuilder sb = new StringBuilder();

			foreach (var meta in Metas)
			{
				if (!string.IsNullOrEmpty(meta.Value))
					sb.AppendLine(@"<meta name=""" + HttpUtility.HtmlEncode(meta.Key) + @""" content=""" + HttpUtility.HtmlEncode(meta.Value) + @""" />");
			}

			if (HeadIncludeFiles != null && HeadIncludeFiles.Count > 0)
			{
				foreach (KeyValuePair<string, IncludeFileType> item in HeadIncludeFiles)
					sb.AppendLine(BuildHeadIncludeHtml(item.Key, item.Value) + "\n");
			}

			return sb.ToString();
		}
	}



	public partial class SpecialPage : ICreator
	{
		public SpecialPageType SpecialPageType
		{
			get
			{
				return (SpecialPageType)PageType;
			}
			set
			{
				PageType = (int)value;
			}
		}

		/// <summary>
		/// 模板文件夹名称。
		/// </summary>
		public string TemplateFolderName
		{
			get
			{
				string templateFile = this.TemplateFile;
				if (string.IsNullOrEmpty(templateFile))
					return null;

				string[] folders = templateFile.Split("/");
				if (folders.Length <= 1) return null;
				return folders[0];
			}
		}
		
		/// <summary>
		/// 模板Url。
		/// </summary>
		public string TemplateRootUrl
		{
			get
			{
				string rootUrl = SpecialPages.TemplateRootUrl;
				string folderName = TemplateFolderName;
				if (string.IsNullOrEmpty(folderName)) return rootUrl;
				return rootUrl + folderName + "/";
			}
		}

		/// <summary>
		/// 模板内容。
		/// </summary>
		public string TemplageContent
		{
			get
			{
				if (!string.IsNullOrEmpty(this.PageTemplate)) return this.PageTemplate;
				return SpecialPages.GetTemplateFileContent(this.TemplateFile);
			}
		}

		[Serializable]
		public class PCI
		{
			public string ModuleType { get; set; }
			public string PageConfiguration { get; set; }
		}

		/// <summary>
		/// 序列化页面配置。
		/// </summary>
		/// <param name="value">进行序列化的配置集合。</param>
		/// <returns>序列化的字符串。</returns>
		public static string SerializePageConfiguration(IEnumerable<SpecialPageConfiguration> value)
		{
			string PageConfiguration;
			if (value == null) PageConfiguration = null;
			else
			{
				List<PCI> cons = new List<PCI>();
				foreach (var val in value)
				{
					if (val == null) continue;

					PCI item = new PCI();
					item.ModuleType = val.ModuleType;
					item.PageConfiguration = SpecialModuleHelper.SerializePageConfiguration(val.ModuleType, val);
					cons.Add(item);
				}

				PageConfiguration = Serialization.SerializeJson(cons);
			}
			return PageConfiguration;
		}

		/// <summary>
		/// 反序列化页面配置。
		/// </summary>
		/// <param name="pageConfiguration">序列化的配置字符串。</param>
		/// <returns>反序列化的配置集合。</returns>
		public static IEnumerable<SpecialPageConfiguration> DeserializePageConfiguration(string pageConfiguration)
		{
			string conStr = pageConfiguration;
			if (string.IsNullOrEmpty(conStr)) return null;

			List<PCI> cons = Serialization.DeserializeJson<List<PCI>>(conStr);
			List<SpecialPageConfiguration> pageCons = new List<SpecialPageConfiguration>();
			foreach (var con in cons)
				pageCons.Add(SpecialModuleHelper.DeserializePageConfiguration(con.ModuleType, con.PageConfiguration));
			return pageCons;
		}

		/// <summary>
		/// 页面配置对象集合。
		/// </summary>
		public IEnumerable<SpecialPageConfiguration> PageConfigurationObjects
		{
			get
			{
				return DeserializePageConfiguration(PageConfiguration);
			}
			set
			{
				PageConfiguration = SerializePageConfiguration(value);
			}
		}
	}




	/// <summary>
	/// 专题页的类型。
	/// </summary>
	[Flags]
	public enum SpecialPageType
	{
		/// <summary>
		/// 聚合页。
		/// </summary>
		Aggregation = 1,
		/// <summary>
		/// 内容页。
		/// </summary>
		Content = 2
	}




	/// <summary>
	/// SpecialPages 类。
	/// </summary>
	public static partial class SpecialPages
	{
		public const string INFO_TYPE = "SpecialPage";
		public const string TemplateConst_Title = "{Title}";
		public const string TemplateConst_TemplateRootUrl = "{TemplateRootUrl}";
		public const string TemplateConst_TemplateFolder = "{TemplateFolder}";
		public const string TemplateConst_HeadAttachedHtml = "{HeadAttachedHtml}";
		public const string TemplateConst_WebsiteNavigation = "{WebsiteNavigation}";
		public const string TemplateConst_MainNavigation = "{MainNavigation}";
		public const string TemplateConst_CurrentLocation = "{CurrentLocation}";
		public const string TemplateConst_CopyrightInfo = "{CopyrightInfo}";
		public const string TemplateConst_ContactTel = "{ContactTel}";


		#region GetIdentifier
		/// <summary>
		/// 根据指定的信息获取专题页标识。
		/// </summary>
		/// <param name="o">专题页的集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>指定的专题页标识。</returns>
		internal static int? GetIdentifier(this System.Data.Linq.Table<SpecialPage> o, int specialId, string pageCode)
		{
			return (from p in o
					where p.SpecialId == specialId && p.PageCode == pageCode
					select (int?)p.PageId).SingleOrDefault();
		}

		/// <summary>
		/// 根据指定的信息获取专题页标识。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>指定的专题页标识。</returns>
		public static int? GetIdentifier(int specialId, string pageCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.GetIdentifier(specialId, pageCode);
		}
		#endregion




		#region GetItem
		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="pageId">获取的专题页标识 PageId。</param>
		/// <param name="pageType">页面的类型。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(this System.Data.Linq.Table<SpecialPage> o, int? pageId, SpecialPageType? pageType)
		{
			var q = from p in o select p;
			if (pageId.HasValue)
				q = q.Where(p => p.PageId == pageId.Value);
			if (pageType.HasValue)
			{
				int type = (int)pageType.Value;
				q = q.Where(p => (p.PageType & type) == type);
			}
			return q.SingleOrDefault();
		}

		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="pageId">获取的专题页标识 PageId。</param>
		/// <param name="pageType">页面的类型。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(int? pageId, SpecialPageType? pageType)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.GetItem(pageId, pageType);
		}

		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="pageId">获取的专题页标识 PageId。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(this System.Data.Linq.Table<SpecialPage> o, int pageId)
		{
			return GetItem(o, pageId, default(SpecialPageType?));
		}

		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="pageId">获取的专题页标识 PageId。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(int pageId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.GetItem(pageId);
		}




		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <param name="pageType">页面的类型。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(this System.Data.Linq.Table<SpecialPage> o, int specialId, string pageCode, SpecialPageType? pageType)
		{
			var q = from p in o where p.SpecialId == specialId select p;
			if (!string.IsNullOrEmpty(pageCode))
				q = q.Where(p => p.PageCode == pageCode);
			if (pageType.HasValue)
			{
				int type = (int)pageType.Value;
				q = q.Where(p => (p.PageType & type) == type);
			}
			return q.SingleOrDefault();
		}

		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <param name="pageType">页面的类型。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(int specialId, string pageCode, SpecialPageType? pageType)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.GetItem(specialId, pageCode, pageType);
		}
		
		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(this System.Data.Linq.Table<SpecialPage> o, int specialId, string pageCode)
		{
			return GetItem(specialId, pageCode, default(SpecialPageType?));
		}

		/// <summary>
		/// 根据标识获取指定的专题页。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialPage GetItem(int specialId, string pageCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.GetItem(specialId, pageCode);
		}
		#endregion



		#region Template
		/// <summary>
		/// 自动察觉专题页的类型。
		/// </summary>
		/// <returns>返回专题页的类型。</returns>
		public static SpecialPageType AutoDetectionPageType(string pageTemplate)
		{
			if (string.IsNullOrEmpty(pageTemplate)) return SpecialPageType.Aggregation;

			Regex reg = new Regex(@" class=""(.* )?ContentArea( .*)?""");
			var match = reg.Match(pageTemplate);
			if(match == Match.Empty) return SpecialPageType.Aggregation;

			return Regex.IsMatch(match.Value, @" class=""(.* )?ModuleArea( .*)?""") ? SpecialPageType.Aggregation | SpecialPageType.Content : SpecialPageType.Content;
		}

		/// <summary>
		/// 自动察觉专题页的类型。
		/// </summary>
		/// <param name="templateFile">专题页的模板文件。</param>
		/// <param name="pageTemplate">专题页的模板内容。</param>
		/// <returns>返回专题页的类型。</returns>
		public static SpecialPageType AutoDetectionPageType(string templateFile, string pageTemplate)
		{
			if (!string.IsNullOrEmpty(pageTemplate)) return AutoDetectionPageType(pageTemplate);
			return AutoDetectionPageType(GetTemplateFileContent(templateFile));
		}

		private static string templateRootUrl = ConfigurationManager.AppSettings["SpecialTemplateRootUrl"];

		public static string TemplateRootUrl
		{
			get
			{
				return string.IsNullOrEmpty(templateRootUrl) ? "/_Specials/Templates/" : templateRootUrl;
			}
		}

		public static string TemplateRootPath
		{
			get
			{
				return System.Web.HttpContext.Current.Server.MapPath(TemplateRootUrl);
			}
		}

		/// <summary>
		/// 获取模板文件内容。
		/// </summary>
		/// <param name="templateFile">模板文件。</param>
		/// <returns>模板文件内容。</returns>
		public static string GetTemplateFileContent(string templateFile)
		{
			if (string.IsNullOrEmpty(templateFile)) return null;
			string file = TemplateRootPath + templateFile;
			if (!File.Exists(file)) return null;

			return File.ReadAllText(file);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的专题页是否已经存在。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="pageId">验证的专题页标识 PageId。</param>
		/// <returns>布尔值表示指定的专题页是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<SpecialPage> o, int pageId)
		{
			return o.Any(p => p.PageId == pageId);
		}

		/// <summary>
		/// 验证指定的专题页是否已经存在。
		/// </summary>
		/// <param name="pageId">验证的专题页标识 PageId。</param>
		/// <returns>布尔值表示指定的专题页是否已经存在。</returns>
		public static bool Exists(int pageId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.Exists(pageId);
		}




		/// <summary>
		/// 验证指定的专题页是否已经存在。
		/// </summary>
		/// <param name="o">专题页集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>布尔值表示指定的专题页是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<SpecialPage> o, int specialId, string pageCode)
		{
			return o.Any(p => p.SpecialId == specialId && p.PageCode == pageCode);
		}

		/// <summary>
		/// 验证指定的专题页是否已经存在。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="pageCode">专题页代码。</param>
		/// <returns>布尔值表示指定的专题页是否已经存在。</returns>
		public static bool Exists(int specialId, string pageCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialPages.Exists(specialId, pageCode);
		}
		#endregion



		#region
		/// <summary>
		/// 获取专题页类别名称。
		/// </summary>
		/// <param name="type">获取的类别。</param>
		/// <returns>类别名称。</returns>
		public static string GetSpecialPageTypeName(SpecialPageType type)
		{
			switch (type)
			{
				case SpecialPageType.Aggregation:
					return "聚合";
				case SpecialPageType.Content:
					return "内容";
			}
			return type.ToString();
		}
		#endregion
	}



	/// <summary>
	/// SpecialPages 类操作部分。
	/// </summary>
	public static partial class SpecialPages
	{
		#region Insert
		/// <summary>
		/// 添加专题页。
		/// </summary>
		/// <param name="insertedSpecialPage">添加的专题页。</param>
		/// <returns>添加的专题页。</returns>
		public static SpecialPage Insert(SpecialPage insertedSpecialPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = insertedSpecialPage.ToNewEntity<SpecialPage>();
			specialPage.CreatorId = Users.CurrentUserId;
			specialPage.CreationDate = DateTime.Now;

			GetInsertRight(dc, specialPage, true);	// 权限验证

			dc.SpecialPages.InsertOnSubmit(specialPage);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Insert", specialPage.PageName);

			// 返回只读数据
			return insertedSpecialPage.FillByEntity(specialPage);
		}
		#endregion



		#region Update
		/// <summary>
		/// 修改专题页名称。
		/// </summary>
		/// <param name="pageId">要修改的专题页标识。</param>
		/// <param name="pageName">修改的名称。</param>
		public static void UpdatePageName(int pageId, string pageName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = dc.SpecialPages.GetItem(pageId);
			if (specialPage == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialPage, true);	// 权限验证

			if (specialPage.PageName == pageName) return;
			specialPage.PageName = pageName;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Update/PageName", specialPage.PageName);

			return;
		}



		/// <summary>
		/// 修改专题页模板文件。
		/// </summary>
		/// <param name="pageId">要修改的专题页标识。</param>
		/// <param name="templateFile">修改的模板文件。</param>
		/// <param name="pageType">页面的类型。</param>
		public static void UpdateTemplateFile(int pageId, string templateFile, SpecialPageType pageType)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = dc.SpecialPages.GetItem(pageId);
			if (specialPage == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialPage, true);	// 权限验证

			//if (specialPage.TemplateFile == templateFile) return;
			specialPage.TemplateFile = templateFile;
			specialPage.PageTemplate = null;
			specialPage.SpecialPageType = pageType;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Update/TemplateFile", specialPage.PageName);

			return;
		}




		/// <summary>
		/// 修改专题页模板。
		/// </summary>
		/// <param name="pageId">要修改的专题页标识。</param>
		/// <param name="pageTemplate">修改的模板代码。</param>
		/// <param name="pageType">页面的类型。</param>
		public static void UpdatePageTemplate(int pageId, string pageTemplate, SpecialPageType pageType)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = dc.SpecialPages.GetItem(pageId);
			if (specialPage == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialPage, true);	// 权限验证

			//if (specialPage.PageTemplate == pageTemplate) return;
			specialPage.PageTemplate = pageTemplate;
			specialPage.SpecialPageType = pageType;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Update/PageTemplate", specialPage.PageName);

			return;
		}




		/// <summary>
		/// 修改模块页面配置。
		/// </summary>
		/// <param name="pageId">要修改的页标识。</param>
		/// <param name="configurations">修改的配置。</param>
		public static void UpdatePageConfiguration(int pageId, IEnumerable<SpecialPageConfiguration> configurations)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = dc.SpecialPages.GetItem(pageId);
			if (specialPage == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialPage, true);	// 权限验证

			specialPage.PageConfigurationObjects = configurations;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Update/PageConfiguration", specialPage.PageName);

			return;
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除专题页。
		/// </summary>
		/// <param name="pageId">删除的专题页标识 PageId。</param>
		public static void Delete(int pageId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialPage specialPage = dc.SpecialPages.GetItem(pageId);
			if (specialPage == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, specialPage, true);	// 权限验证

			Delete(dc, specialPage);

			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialPage.PageId.ToString(), "Delete", specialPage.PageName);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, SpecialPage specialPage)
		{
			dc.SpecialPages.DeleteOnSubmit(specialPage);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, Special parent)
		{
			IEnumerable<SpecialPage> e = parent.SpecialPages.AsEnumerable();
			foreach (SpecialPage i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// SpecialPages 类对应操作权限部分。
	/// </summary>
	public static partial class SpecialPages
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加专题页的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialPage">添加的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加专题页的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, SpecialPage specialPage, bool triggerException)
		{
			Special special = Specials.GetItem(specialPage.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加专题页的权限。
		/// </summary>
		/// <param name="specialPage">添加的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加专题页的权限。</returns>
		public static bool GetInsertRight(SpecialPage specialPage, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), specialPage, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加专题页的权限。
		/// </summary>
		/// <param name="specialPage">添加的专题页对象。</param>
		/// <returns>布尔值表示当前用户是否有添加专题页的权限。</returns>
		public static bool GetInsertRight(SpecialPage specialPage)
		{
			return GetInsertRight(specialPage, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新专题页的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialPage">更新的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新专题页的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, SpecialPage specialPage, bool triggerException)
		{
			Special special = Specials.GetItem(specialPage.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新专题页的权限。
		/// </summary>
		/// <param name="specialPage">更新的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新专题页的权限。</returns>
		public static bool GetUpdateRight(SpecialPage specialPage, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), specialPage, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新专题页的权限。
		/// </summary>
		/// <param name="specialPage">更新的专题页对象。</param>
		/// <returns>布尔值表示当前用户是否有更新专题页的权限。</returns>
		public static bool GetUpdateRight(SpecialPage specialPage)
		{
			return GetUpdateRight(specialPage, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除专题页的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialPage">删除的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除专题页的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, SpecialPage specialPage, bool triggerException)
		{
			Special special = Specials.GetItem(specialPage.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除专题页的权限。
		/// </summary>
		/// <param name="specialPage">删除的专题页对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除专题页的权限。</returns>
		public static bool GetDeleteRight(SpecialPage specialPage, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), specialPage, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除专题页的权限。
		/// </summary>
		/// <param name="specialPage">删除的专题页对象。</param>
		/// <returns>布尔值表示当前用户是否有删除专题页的权限。</returns>
		public static bool GetDeleteRight(SpecialPage specialPage)
		{
			return GetDeleteRight(specialPage, false);
		}
		#endregion
	}



	/// <summary>
	/// SpecialPages 类后台管理部分。
	/// </summary>
	public static partial class SpecialPages
	{
		public struct SpecialPageForManageList
		{
			public int PageId { get; set; }
			public int SpecialId { get; set; }
			public string PageCode { get; set; }
			public string PageName { get; set; }
			public int PageType { get; set; }

			public SpecialPageType SpecialPageType
			{
				get
				{
					return (SpecialPageType)PageType;
				}
				set
				{
					PageType = (int)value;
				}
			}
		}

		private static IQueryable<SpecialPageForManageList> GetManageListQuery(GenericModuleDataContext dc, int? specialId, SpecialPageType? pageType, string keyword)
		{
			IQueryable<SpecialPageForManageList> q;

			q = from p in dc.SpecialPages
				select new SpecialPageForManageList { PageId = p.PageId, SpecialId = p.SpecialId, PageCode = p.PageCode, PageName = p.PageName, PageType = p.PageType };

			if (specialId.HasValue)
				q = q.Where(p => p.SpecialId == specialId.Value);

			if (pageType.HasValue)
			{
				int type = (int)pageType.Value;
				q = q.Where(p => (p.PageType & type) == type);
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.PageCode.Contains(keyword) || p.PageName.Contains(keyword));

			return q;
		}

		public static PaginationInfo<List<SpecialPageForManageList>> GetPaginationManageList(int? specialId, SpecialPageType? pageType, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetManageListQuery(dc, specialId, pageType, keyword);

			PaginationInfo<List<SpecialPageForManageList>> pageInfo = new PaginationInfo<List<SpecialPageForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<SpecialPageForManageList> GetManageList(int? specialId, SpecialPageType? pageType, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetManageListQuery(dc, specialId, pageType, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}
	}
}